<template>
  <q-layout view="hHh Lpr lFf" @click="handleClick">
    <q-page-container v-if="!isIframe">
      <router-view
        :currentSong="musicPlayerRef"
        :songHistory="musicHistory"
        @play-song="handlePlaySong"
        @import-history="handleImportHistory"
        @clear-history="handleClearHistory"
        @refresh-history="GetHistoryFromBucket"
        :isClicked="isClicked"
        :isLogin="isLogin"
      />
    </q-page-container>
    <q-footer>
      <MusicPlayer
        class="absolute-bottom player-style text-black"
        :currentSong="musicPlayerRef"
        :songHistory="musicHistory"
        @update-duration="handleUpdateDuration"
        :isClicked="isClicked"
        @update-history="handleUpdateHistory"
        @update-song="handleChangeSong"
      />
    </q-footer>
  </q-layout>

  <q-spinner-ios
    v-if="isLoading"
    class="absolute-top"
    style="top: 20px; left: 20px"
    color="primary"
    size="20px"
  />
</template>

<script setup>
import MusicPlayer from 'src/components/MusicPlayer.vue'
import { ref, onMounted, onUnmounted } from 'vue'
import { useRouter } from 'vue-router'
import { api } from 'src/boot/axios'
import { useQuasar, Loading, QSpinnerIos } from 'quasar'

const $q = useQuasar()
const router = useRouter()
const isIframe = ref(false)
defineOptions({
  name: 'MainLayout',
})

const musicPlayerRef = ref({
  title: '音乐名称',
  artist: '作家',
  duration: 0,
  url: '',
})
const musicHistory = ref([])
const isLogin = ref(false)
const email = ref('')
const token = ref('')
const isLoading = ref(false)
const userInfo = ref({})
const checkStatusTimer = ref(null)

const handleChangeHistory = (newHistory) => {
  // 创建本地记录映射表（保留已有isCloud标记）
  const localMap = new Map(
    musicHistory.value.map((item) => [
      item.url,
      {
        ...item,
        isCloud: Object.prototype.hasOwnProperty.call(item, 'isCloud') ? item.isCloud : false,
      },
    ]),
  )

  // 创建云端记录映射表（强制标记为true）
  const cloudMap = new Map(newHistory.map((item) => [item.url, { ...item, isCloud: true }]))

  // 合并记录（云端优先）
  const mergedMap = new Map([...localMap, ...cloudMap])
  musicHistory.value = Array.from(mergedMap.values())
}

const GetHistoryFromBucket = async () => {
  try {
    isLoading.value = true
    const res = await api.get('/api/v1/music_json_service', {
      headers: {
        ApiKey: btoa(
          `${localStorage.getItem('token') || ''}` +
            '$$' +
            `${localStorage.getItem('email') || ''}`,
        ),
      },
    })
    handleChangeHistory(res.data.config)
    $q.notify({
      message: '历史记录已更新',
      color: 'positive',
      position: 'top',
    })
  } catch (ex) {
    console.log(ex)
    // if response has exists "message or error". use $q.Notify to show the message/error in top
    if (ex.response?.data?.message) {
      $q.notify({
        message: '获取云端历史记录失败：' + ex.response.data.message,
        color: 'negative',
        position: 'top',
      })
    }
    if (ex.response?.data?.error) {
      $q.notify({
        message: '获取云端历史记录失败：' + ex.response.data.error,
        color: 'negative',
        position: 'top',
      })
    }
  } finally {
    isLoading.value = false
  }
}

const handleLoginStatus = async () => {
  try {
    isLoading.value = true

    const statusRes = await api.get('/api/v1/user_info', {
      headers: {
        ApiKey: btoa(
          `${localStorage.getItem('token') || ''}` +
            '$$' +
            `${localStorage.getItem('email') || ''}`,
        ),
      },
    })
    userInfo.value = statusRes.data
    isLogin.value = true
    if (!checkStatusTimer.value) {
      checkStatusTimer.value = setInterval(
        async () => {
          await handleLoginStatus()
        },
        1000 * 60 * 30,
      )
    }
  } catch (e) {
    console.error(e)
    isLogin.value = false
    if (checkStatusTimer.value) {
      clearInterval(checkStatusTimer.value)
      checkStatusTimer.value = null
    }
  } finally {
    isLoading.value = false
  }
}

const isClicked = ref(false)
const handleClick = () => {
  isClicked.value = true
  console.log('用户已经点击的网页')
}
onMounted(async () => {
  Loading.setDefaults({
    spinner: QSpinnerIos,
    spinnerSize: 40,
    spinnerColor: 'grey-8',
    backgroundColor: 'grey-3',
  })

  $q.loading.show()
  // get LoginData from query
  const query = router.currentRoute.value.query
  console.log(query)
  if (query?.LoginData) {
    const loginDataBase64 = JSON.parse(decodeURIComponent(query.LoginData))
    const LoginDataJSON = atob(loginDataBase64)
    const loginData = JSON.parse(LoginDataJSON)
    Object.entries(loginData).forEach(([key, value]) => {
      localStorage.setItem(key, value)
    })
    // remove LoginData from query
    await router.replace({
      path: router.currentRoute.value.path,
      query: {},
    })
    location.href = location.origin + '/#/' + (location.href.split('/#/')[1] || '')
    return
  }
  if (location.search.includes('LoginData')) {
    // get params from query
    const params = new URLSearchParams(location.search)
    const LoginDataBase64 = params.get('LoginData')
    const LoginDataJSON = atob(LoginDataBase64)
    const loginData = JSON.parse(LoginDataJSON)
    Object.entries(loginData).forEach(([key, value]) => {
      localStorage.setItem(key, value)
    })
    // remove the url query
    location.search = ''
    location.href = location.origin + '/#/' + (location.href.split('/#/')[1] || '')
    return
  }
  email.value = localStorage.getItem('email') || ''
  token.value = localStorage.getItem('token') || ''
  if (email.value && token.value) {
    await handleLoginStatus()
    if (isLogin.value) {
      await GetHistoryFromBucket()
    }
  }

  isIframe.value = window.self !== window.top
  console.log('当前页面是否在iframe中:', isIframe)

  let isNewSong = false

  const history = localStorage.getItem('musicHistory')
  if (history) {
    try {
      musicHistory.value = JSON.parse(history).map((item) => ({
        ...item,
        isCloud: Object.prototype.hasOwnProperty.call(item, 'isCloud') ? item.isCloud : false,
      }))
    } catch {
      musicHistory.value = []
      localStorage.setItem('musicHistory', '[]')
    }
  }
  let src = ''
  if (query?.src) {
    src = query.src
    musicPlayerRef.value.url = query.src
    musicPlayerRef.value.title = query?.title || '未知歌曲'
    musicPlayerRef.value.artist = query?.artist || '未知艺术家'
    musicPlayerRef.value.duration = query?.duration || 0
    if (!musicHistory.value.find((item) => item.url === query.src)) {
      isNewSong = true
    }
  } else if (location.search.includes('src')) {
    const params = new URLSearchParams(location.search)
    musicPlayerRef.value.url = params.get('src')
    src = params.get('src')
    musicPlayerRef.value.title = params.get('title') || '未知歌曲'
    musicPlayerRef.value.artist = params.get('artist') || '未知艺术家'
    musicPlayerRef.value.duration = params.get('duration') || 0
    if (!musicHistory.value.find((item) => item.url === params.get('src'))) {
      isNewSong = true
    }
  }

  if (isNewSong) {
    musicHistory.value.unshift({
      title: musicPlayerRef.value.title,
      artist: musicPlayerRef.value.artist,
      duration: musicPlayerRef.value.duration,
      url: musicPlayerRef.value.url,
      isCloud: false,
    })
    localStorage.setItem('musicHistory', JSON.stringify(musicHistory.value))
  } else if (src) {
    // change element value
    const index = musicHistory.value.findIndex((item) => item.url === query.src)
    musicHistory.value[index] = {
      title: musicPlayerRef.value.title,
      artist: musicPlayerRef.value.artist,
      duration: musicPlayerRef.value.duration,
      url: musicPlayerRef.value.url,
    }
  }
  $q.loading.hide()
})

onUnmounted(() => {
  if (checkStatusTimer.value) {
    clearInterval(checkStatusTimer.value)
    checkStatusTimer.value = null
  }
})

const handlePlaySong = (index) => {
  musicPlayerRef.value = musicHistory.value[index]
}

const handleChangeSong = (newSong) => {
  musicPlayerRef.value = newSong
}

const handleUpdateDuration = ({ url, duration }) => {
  const index = musicHistory.value.findIndex((item) => item.url === url)
  if (index !== -1) {
    musicHistory.value[index].duration = duration
    musicHistory.value[index].title = musicPlayerRef.value.title
    musicHistory.value[index].artist = musicPlayerRef.value.artist
    localStorage.setItem('musicHistory', JSON.stringify(musicHistory.value))
  }
}

const handleClearHistory = () => {
  musicHistory.value = []
  localStorage.setItem('musicHistory', '[]')
}

const handleImportHistory = (data) => {
  if (Array.isArray(data)) {
    musicHistory.value = data
    localStorage.setItem('musicHistory', JSON.stringify(data))
  }
}
</script>

<style scoped>
.player-style {
  width: 100%;
  max-width: 1000px;
  justify-self: anchor-center;
}
</style>
